package in.animeshpathak.appic;

import java.io.File;
import java.io.IOException;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.entity.FileEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;


public class HomeActivity extends Activity {


	//ID of the uploading dialog box
	private static final int DIALOG_UPLOADING = 0;


	private String apiUrl = "";
	private String apiUName = "";
	private String apiPass = "";
	private File imageFile;

	private String serverResponse;

	private Uri imageUri = null;

	TextView console;

	final Handler h =  new Handler();

	final Runnable showServerResponse = new Runnable(){
		public void run(){
			dismissDialog(DIALOG_UPLOADING);
			Log.d(Constants.HOME_ACTIVITY_LOGTAG,"\nUpload Complete. The Server said...\n");
			Log.d(Constants.HOME_ACTIVITY_LOGTAG, serverResponse);

			console.append("\nUpload Complete. The Server said...\n");
			console.append(serverResponse);
		}
	};


	private Uri thumbUri;


	@Override
	/** Called when the activity is first created. */
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.main_relative);

		this.console = (TextView)findViewById(R.id.consoleResponse);

		//setting handlers for the pick button
		Button pickButton = (Button)findViewById(R.id.pickFileButton);
		pickButton.setOnClickListener(new OnClickListener(){
			// Implement the OnClickListener callback for the file chooser.
			public void onClick(View v) {
				// do something when the button is clicked
				Log.d(Constants.HOME_ACTIVITY_LOGTAG, "button FilePicker clicked!");

				//Creating an intent for image picker. 
				Intent chooserIntent = new Intent(Intent.ACTION_PICK,
						android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
				//Start the activity, wait for result
				startActivityForResult(chooserIntent, Constants.PICK_IMAGE_REQUEST);
			}
		});

		//setting handler for the Upload button
		Button uploadButton = (Button)findViewById(R.id.upload);
		uploadButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				//clear console
				console.setText("");

				Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Upload button clicked!");

				//get image Title. See if it is blank.
				String imageTitle = ((EditText)findViewById(R.id.imageTitle)).getText().toString();
				if (imageTitle.equalsIgnoreCase("")){
					Log.e(Constants.HOME_ACTIVITY_LOGTAG, "Blank image title passed! NOT uploading");
					console.append("Sorry. Image Title Cannot be blank. Cannot upload");
					return;
				}

				//get file path URI. See if it is null
				Uri filePathUri = imageUri; 
				Log.d(Constants.HOME_ACTIVITY_LOGTAG, "File Path Uri is: " + filePathUri );

				if (filePathUri == null){
					Log.e(Constants.HOME_ACTIVITY_LOGTAG, "Null Uri passed for image! NOT uploading");
					console.append("Sorry. Null Image URI. Cannot upload");
					return;

				}

				String filePath = getRealPathFromURI(filePathUri);
				Log.d(Constants.HOME_ACTIVITY_LOGTAG, "File Path is: " + filePath );
				File f = new File(filePath);
				if (f != null){
					//valid file
					long imageFileSize = f.length();
					Log.d(Constants.HOME_ACTIVITY_LOGTAG,"File size (in bytes) is: " + imageFileSize);

					if(imageFileSize > Constants.MAX_SIZE_BYTES){
						Log.d(Constants.HOME_ACTIVITY_LOGTAG, "File size ("+ imageFileSize +" bytes) larger than "
								+ Constants.MAX_SIZE_BYTES + ". Cannot upload.");
						console.append("File size ("+ imageFileSize +" bytes) larger than "
								+ Constants.MAX_SIZE_BYTES + ". Cannot upload.");
					}else{
						//get Stored preferences back
						getStoredPreferenceData();
						Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Using apiUrl: " + apiUrl);
						Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Using apiUname: " + apiUName);
						//for production code
						Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Using apiPass: " + "*** ;-) ");


						if (apiUrl.equalsIgnoreCase("")){
							Log.e(Constants.HOME_ACTIVITY_LOGTAG, "Blank API URL. Oops");
							console.append("Sorry. Blank API URL. Cannot upload. Click Menu->settings to update.");
							return;
						}

						if (apiUName.equalsIgnoreCase("")){
							Log.e(Constants.HOME_ACTIVITY_LOGTAG, "Blank API Username. Oops");
							console.append("Sorry. Blank API Username. Cannot upload. Click Menu->settings to update.");
							return;
						}

						//set file
						imageFile = f;

						//proceed to upload?
						console.append("Uploading " + filePathUri + " to " + apiUrl + " ...");

						//show spinning dialog
						showDialog(DIALOG_UPLOADING);

						//start uploader thread.
						ImageUploader myImageUploader = new ImageUploader(); 
						myImageUploader.setParameters(apiUrl, apiUName, apiPass, imageTitle, f);
						myImageUploader.start();

					}

				}else{
					Log.d(Constants.HOME_ACTIVITY_LOGTAG,"Cannot open file at " + filePath + ". Oops.");
				}

			}
		});

	}




	/**
	 * Getting the data stored in "settings"
	 */
	private void getStoredPreferenceData() {
		// Restore preferences
		SharedPreferences settings = getSharedPreferences(Constants.PREFS_NAME, 0);
		this.apiUrl = settings.getString(Constants.APIURL_PREFS_KEY, "");
		Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Got stored apiUrl " + this.apiUrl);

		this.apiUName = settings.getString(Constants.APIUNAME_PREFS_KEY, "");
		Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Got stored apiUName " + this.apiUName);

		this.apiPass = settings.getString(Constants.APIPASS_PREFS_KEY, "");
		//Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Got stored apiPass " + this.apiPass);
		//for production code
		Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Got stored apiPass " + "*** ;-)");

	}




	protected Dialog onCreateDialog(int id) {
		Dialog dialog;
		switch(id) {
		case DIALOG_UPLOADING:
			// do the work to define the pause Dialog
			dialog = new ProgressDialog(HomeActivity.this);
			dialog.setTitle("Uploading file. Please wait...");
			break;
		default:
			dialog = null;
		}
		return dialog;
	}


	@Override
	/**
	 * implementing what happens after the file chooser returns.
	 */
	protected void onActivityResult(int requestCode, int resultCode,
			Intent data) {
		if (requestCode == Constants.PICK_IMAGE_REQUEST) {
			if (resultCode == RESULT_OK) {
				//a valid image was returned! yay!
				Log.d(Constants.HOME_ACTIVITY_LOGTAG,"File chooser returned successful");
				Log.d(Constants.HOME_ACTIVITY_LOGTAG,"File path: "+ data.getData());
				this.imageUri = data.getData();
				TextView filePath = (TextView)findViewById(R.id.filePath);
				filePath.setText(data.getDataString());
				
				String thumbUriBase = android.provider.MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI.toString();
				String ID = imageUri.getLastPathSegment();
				this.thumbUri = Uri.parse(thumbUriBase + "/" + ID);
				
				ImageView imageThumb = (ImageView)findViewById(R.id.photoThumbnailView);
				imageThumb.setAdjustViewBounds(true);
				imageThumb.setMaxHeight(100);
				imageThumb.setMaxWidth(100);
				imageThumb.setImageURI(thumbUri);

				
			} else{
				//oops. No images found.
				Log.d(Constants.HOME_ACTIVITY_LOGTAG, "No image chosen. Doing nothing");
			}
		}
	}


	/**
	 * Converts the image URI to the direct file system path of the image file. Taken from
	 * http://russenreaktor.wordpress.com/2010/02/20/solved-android-get-file-path-of-gallery-image/
	 * @param contentUri The image URI
	 * @return a raw file path
	 */
	public String getRealPathFromURI(Uri contentUri) {
		// can post image
		String [] proj={MediaStore.Images.Media.DATA};
		Cursor cursor = managedQuery( contentUri,
				proj, // Which columns to return
				null, // WHERE clause; which rows to return (all rows)
				null, // WHERE clause selection arguments (none)
				null); // Order-by clause (ascending by name)
		int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
		cursor.moveToFirst();
		return cursor.getString(column_index);
	}	


	@Override
	protected void onSaveInstanceState (Bundle outState){

		super.onSaveInstanceState(outState);

		//store image title
		String imageTitle = ((EditText)findViewById(R.id.imageTitle)).getText().toString();
		Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Saving image title: " + imageTitle);
		outState.putString(Constants.TITLE_KEY, imageTitle);
		//store image path as string
		String imagePath = ((TextView)findViewById(R.id.filePath)).getText().toString();
		Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Saving image path string " + imagePath);
		outState.putString(Constants.IMAGE_PATH_STRING_KEY,imagePath);		
		//store image Uri
		Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Saving image Uri " + this.imageUri);
		outState.putParcelable(Constants.IMAGE_PATH_URI_KEY, this.imageUri);
		//store image thumb Uri
		Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Saving image thumb Uri " + this.thumbUri);
		outState.putParcelable(Constants.IMAGE_THUMB_URI_KEY, this.thumbUri);

	}

	@Override
	protected void onRestoreInstanceState (Bundle savedInstanceState){

		super.onRestoreInstanceState(savedInstanceState);

		//retrieve image title
		String imageTitle = savedInstanceState.getString(Constants.TITLE_KEY);
		if (imageTitle != null){
			Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Resumed. Got imageTitle " + imageTitle );
			EditText e = (EditText)findViewById(R.id.imageTitle);
			e.setText(imageTitle);
		}else{
			Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Resumed. Got Null imageTitle");
		}

		//retrieve image
		String imagePathUri = savedInstanceState.getString(Constants.IMAGE_PATH_STRING_KEY);
		if (imagePathUri != null){
			Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Resumed. Got imagePath string " + imagePathUri );
			TextView t = (TextView)findViewById(R.id.filePath);
			t.setText(imagePathUri);
		}else{
			Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Resumed. Got Null imagePath string");
		}

		Uri imageUri = (Uri)savedInstanceState.getParcelable(Constants.IMAGE_PATH_URI_KEY);
		if (imageUri != null){
			Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Resumed. Got imageUri " + imageUri);
			this.imageUri = imageUri;
		}else{
			Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Resumes. Got Null imageUri");
		}

		Uri thumbUri = (Uri)savedInstanceState.getParcelable(Constants.IMAGE_THUMB_URI_KEY);
		if (thumbUri != null){
			Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Resumed. Got thumbUri " + thumbUri);
			this.thumbUri = thumbUri;
			ImageView imageThumb = (ImageView)findViewById(R.id.photoThumbnailView);
			imageThumb.setAdjustViewBounds(true);
			imageThumb.setMaxHeight(100);
			imageThumb.setMaxWidth(100);
			imageThumb.setImageURI(thumbUri);
		}else{
			Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Resumes. Got Null thumbUri");
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.main_menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle item selection
		switch (item.getItemId()) {
		case R.id.settings:
			Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Settings menu button clicked!");
			Intent i = new Intent(this, SettingsActivity.class);
			startActivity(i);
			return true;
		case R.id.exit:
			Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Exit menu button clicked! Bye bye.");
			moveTaskToBack(true);
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	/** 
	 * Make an HTTP post request with a file.
	 * This is based on http://stackoverflow.com/questions/3038409/how-to-send-http-post-request-and-recieve-response/3038747#3038747
	 * 
	 * @param url
	 * @param data
	 * @return
	 */
	public String postPage(String url, File data) {

		String ret = null;

		DefaultHttpClient httpClient = new DefaultHttpClient();

		httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109);

		HttpPost httpPost = new HttpPost(url);
		HttpResponse response = null;

		FileEntity tmp = null;       

		tmp = new FileEntity(data,"UTF-8");

		httpPost.setEntity(tmp);

		try {
			response = httpClient.execute(httpPost);
		} catch (ClientProtocolException e) {
			System.out.println("HTTPHelp : ClientProtocolException : "+e);
		} catch (IOException e) {
			System.out.println("HTTPHelp : IOException : "+e);
		} 
		ret = response.getStatusLine().toString();

		return ret;
	}

	/**
	 * The thread that uploads the image
	 * @author animesh
	 *
	 */
	class ImageUploader extends Thread{
		private String apiUrl;
		private String apiUName;
		private String apiPass;
		private String imageTitle;
		private File imageFile;

		public void setParameters(String apiUrl, String apiUName, String apiPass, 
				String imageTitle, File imageFile){
			this.apiUrl = apiUrl;
			this.apiUName = apiUName;
			this.apiPass = apiPass;
			this.imageTitle = imageTitle;
			this.imageFile = imageFile;
		}

		/**
		 * performs the actual file upload. Uses local variables. Be sure to set them before calling this.
		 * Thanks to http://stackoverflow.com/questions/2935946/sending-images-using-http-post
		 * @return The response received from the server.
		 */
		private String uploadFile(){
			Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Using apiURL " + this.apiUrl);
			Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Using apiUName " + this.apiUName);
			Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Using apiPass " + this.apiPass);

			if(imageFile == null){
				Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Null file for upload! WTF!");
				return "File not found. Weird.";
			}

			HttpClient httpClient = new DefaultHttpClient();
			HttpContext localContext = new BasicHttpContext();
			HttpPost httpPost = new HttpPost(apiUrl);

			String responseCode;

			try {
				MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

				//add title
				entity.addPart(Constants.TITLE_PART_NAME, new StringBody(imageTitle));
				//add username
				entity.addPart(Constants.UNAME_PART_NAME, new StringBody(apiUName));
				//add password
				entity.addPart(Constants.PASSWORD_PART_NAME, new StringBody(apiPass));

				//add the file itself.
				entity.addPart(Constants.IMAGE_PART_NAME, new FileBody(imageFile));

				httpPost.setEntity(entity);

				HttpResponse response = httpClient.execute(httpPost, localContext);

				responseCode = response.getStatusLine().toString();



			} catch (IOException e) {
				e.printStackTrace();
				Log.e(Constants.HOME_ACTIVITY_LOGTAG, 
						"Upload had a problem. Here's why: " + e.toString(),e);
				return "Upload had a problem.\n"+e.toString();
			}

			//			return "Hello there! How're _you_ doin? No upload actually happened. " +
			//			"But can you please send any bug reports to animesh@gmail? Thanks.";

			return responseCode;
		}

		public void run(){
			// upload File and get server response
			serverResponse = uploadFile();
			//dismiss the dialog
			Log.d(Constants.HOME_ACTIVITY_LOGTAG, "Done doing my stuff. " +
					"\nGot response: " + serverResponse +
			"Sending message for dismissing dialog now.");

			h.post(showServerResponse);

		}
	};


}

